package com.it.product.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.it.product.domain.Category;
import com.it.product.domain.vo.CategoryExcelVo;
import com.it.product.helper.CategoryHelper;
import com.it.product.mapper.CategoryMapper;
import com.it.product.service.ICategoryService;
import com.spzx.common.core.utils.bean.BeanUtils;

import com.spzx.product.api.domain.vo.CategoryVo;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * projectName: spzx-parent
 *
 * @author: 王宝贵
 * time: 2024/9/20 19:08 周五
 * description:
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {

    @Autowired
    CategoryMapper categoryMapper;

    /**
     * 查询商品分类
     * @param id 父类的id
     * @return
     * 首先是一级标签id 返回的多个2级的数据 后面会根句单个2级标签的id查询多个三级标签信息
     */
    @Override
    public List<Category> treeSelect(Long id) {
        LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Category> queryWrapper = lambdaQueryWrapper.eq(Category::getParentId, id);

        //根据id查找所属的全部信息
        List<Category> categoryList = categoryMapper.selectList(queryWrapper);

        //判断是否还是下级
        if(!CollectionUtils.isEmpty(categoryList)){
            //遍历
            categoryList.forEach(new Consumer<Category>() {
                @Override
                public void accept(Category itm) {
                    //统计是否还有下级
                    Long aLong = categoryMapper.selectCount(new LambdaQueryWrapper<Category>().eq(Category::getParentId, itm.getId()));
                    if(aLong>0){
                        itm.setHasChildren(true);
                    }else {
                        itm.setHasChildren(false);
                    }

                }
            });

        }
        return categoryList;
    }

    /**
     * 根据c的主键 递归查询 3 2 1级标签的主键
     * @param categoryId
     * @return
     */
    @Override
    public List<Long> selectListById(Long categoryId) {
        List<Category> categoryList = new ArrayList<>();
        List<Category> categories = selectBys(categoryId, categoryList);
        ArrayList<Long> longArrayList = new ArrayList<>();
        categories.forEach(category -> longArrayList.add(category.getId()));
        return longArrayList;
    }

    /**
     * 根据c的主键 递归查询 3 2 1级标签的主键
     * @return
     */
    private List<Category> selectBys(Long id,List<Category> categoryList ){
        //先根据主键查询3级标签的父类信息
        Category category = categoryMapper.selectById(id);
        //判断是否还有父类标签
        if(category.getParentId()>0){
            selectBys(category.getParentId(),categoryList);
        }
        //递归查询到是 3 2 1放到集合里面是 1 2 3 递归出口后再从里面开始添加
        categoryList.add(category);
        return categoryList;
    }

    /**
     * 数据导出 TODO 数据的导出
     * @param
     */
    @Override
    public void export(HttpServletResponse response) throws Exception {
        //1.设置编码格式 前端以excel类型返回给前端
        response.setContentType("application/vnd.ms-excel"); //参考：tomcat/conf/web.xml文件 <mime-mapping>
        response.setCharacterEncoding("UTF-8");

        //2.设置响应头
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("分类数据","UTF-8");
        response.setHeader("Content-disposition","attachment;filename=" +fileName +".xlsx"); //告诉前端以附件形式打开 另存为
        response.setHeader("Access-Control-Expose-Headers","Content-Disposition");

        //3.查询数据库数据
        List<Category> categories = categoryMapper.selectList(null);
        ArrayList<CategoryExcelVo> categoryArrayList = new ArrayList<>(categories.size());

        //4.将数据Category对象转换问 CategoryExcelVo对象类型
        categoryArrayList.forEach(category ->{
            CategoryExcelVo categoryExcelVo = new CategoryExcelVo();
            BeanUtils.copyBeanProp(category,categoryExcelVo);
            categoryArrayList.add(categoryExcelVo);
        } );

        //写出数据到浏览器
        EasyExcel.write(response.getOutputStream(),CategoryExcelVo.class).sheet("分类数据").doWrite(categoryArrayList);

    }

    /**
     * 数据到入
     * @param file
     */
    @Override
    public void importData(MultipartFile file) throws Exception {
        //解析数据
        List<CategoryExcelVo> objectList = EasyExcel.read(file.getInputStream()).head(CategoryExcelVo.class).sheet().doReadSync();

        //判断 加复制数据
        if(CollectionUtils.isEmpty(objectList)){
            ArrayList<Category> categories = new ArrayList<>(objectList.size());
            for (CategoryExcelVo categoryExcelVo : objectList) {
                Category category = new Category();

                BeanUtils.copyProperties(categoryExcelVo,category,Category.class);
                categories.add(category);
            }
            //添加到数据库
            this.saveBatch(categories);
        }

    }


    @Override
    public List<CategoryVo> getOneCategory() {
        //TODO copyProperties 不是copyBeanProp
        List<Category> categoryList = categoryMapper.selectList(new LambdaQueryWrapper<Category>().eq(Category::getParentId, 0));

        List<CategoryVo> collect = categoryList.stream().map(itm -> {
            CategoryVo categoryVo = new CategoryVo();
            BeanUtils.copyProperties(itm, categoryVo);
            return categoryVo;
        }).collect(Collectors.toList());
        return collect;

    }

    /**
     * 远程调用category 查询所有的远程 一级分类
     * @return 返回的是集合
     */
    @Override
    public List<CategoryVo> tree() {
        List<Category> categoryList = this.list();
        //拷贝成vo数据
        List<CategoryVo> categoryVoList = categoryList.stream().map(item -> {
            CategoryVo categoryVo = new CategoryVo();
            BeanUtils.copyProperties(item, categoryVo);
            return categoryVo;
        }).toList();
        //此时返回的是一级目录 还没有子目录 需要使用到递归对数据进行分类
        List<CategoryVo> categoryVos = CategoryHelper.buildTree(categoryVoList);
        return categoryVos;
    }
}